package gestion.camping.utils;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * Utilitaire pour l'internationalisation des messages
 */
public final class MessagesUtil {
	
	// Attributs

	/**
	 * Les noms des bundles
	 */
	private static String[] bundlesNames = null;

	/**
	 * La liste des bundles pour la locale
	 */
	private static final Map<Locale, List<ResourceBundle>> bundles = new HashMap<Locale, List<ResourceBundle>>();

	/**
	 * La locale utilisée
	 */
	private static Locale locale = Locale.getDefault();

	/**
	 * Le classloader utilisé
	 */
	public static ClassLoader classLoader = null;

	// Constructeur

	/**
	 * Construit le MessagesUtil
	 */
	private MessagesUtil() {
		super();
	}

	// Méthodes utiles

	/**
	 * Initialise les bundles
	 * 
	 * @param names
	 *            la liste des noms des bundles
	 */
	public static void init(String... names) {
		init(Locale.getDefault(), names);
	}

	/**
	 * Initialise les bundles
	 * 
	 * @param newLocale
	 *            la locale par défaut
	 * @param names
	 *            la liste des noms des bundles
	 */
	public static void init(Locale newLocale, String... names) {
		bundles.clear();
		locale = newLocale;
		bundlesNames = names.clone();
		bundles.put(newLocale, getBundles(newLocale));
	}

	/**
	 * Récupère les bundles correspondant à la locale
	 * 
	 * @param newLocale
	 *            la locale
	 */
	private static List<ResourceBundle> getBundles(Locale newLocale) {
		List<ResourceBundle> result = new ArrayList<ResourceBundle>();
		if (bundlesNames != null) {
			ResourceBundle bundle = null;
			for (String bundleName : bundlesNames) {
				try {

					if (bundleName != null) {
						if (classLoader != null) {
							bundle = ResourceBundle.getBundle(bundleName.trim(), newLocale, classLoader);
						} else {
							bundle = ResourceBundle.getBundle(bundleName.trim(), newLocale);
						}
						result.add(bundle);
					}
				} catch (MissingResourceException mre) {
					System.err.println("Impossible de trouver le bundle \""+ bundleName+"\"");
				}
			}
		}
		return result;
	}

	/**
	 * Format le message
	 * 
	 * @param messageKey
	 *            la clef du messages
	 * @param args
	 *            les arguments des messages
	 * @return le message formaté
	 */
	public static String formatMessage(String messageKey, Object... args) {
		return formatMessage(messageKey, null, args);
	}

	/**
	 * Format le message
	 * 
	 * @param messageKey
	 *            la clef du messages
	 * @param newLocale
	 *            la locale
	 * @param args
	 *            les arguments des messages
	 * @return le message formaté
	 */
	public static String formatMessage(String messageKey, Locale newLocale, Object... args) {
		String i18nMessage = null;
		MessageFormat format = null;
		if (newLocale == null || newLocale.equals(locale)) {
			i18nMessage = getMessage(messageKey);
			format = new MessageFormat(i18nMessage, locale);
		} else {
			i18nMessage = getMessage(messageKey, newLocale);
			format = new MessageFormat(i18nMessage, newLocale);
		}
		return format.format(args);
	}

	/**
	 * Récupère le message internationalisé
	 * 
	 * @param messageKey
	 *            la clef du message
	 * @return le message internationalisé
	 */
	private static String getMessage(String messageKey) {
		return getMessage(messageKey, locale);
	}

	/**
	 * Récupère le message internationalisé
	 * 
	 * @param messageKey
	 *            la clef du message
	 * @param locale
	 *            la locale
	 * @return le message internationalisé
	 */
	private static String getMessage(String messageKey, Locale newLocale) {
		List<ResourceBundle> bList = bundles.get(newLocale);
		if (bList == null) {
			bList = getBundles(newLocale);
			bundles.put(newLocale, bList);
		}
		String result = getMessageForBundles(messageKey, bList);
		// cas ou on n'a pas trouvé la clef
		if (result == null) {
			System.err.println("Impossible de trouver la clef \""+ messageKey+"\" dans les fichiers de messages");
			StringBuilder resultTmp = new StringBuilder(8);
			resultTmp.append("??? ");
			resultTmp.append(messageKey);
			resultTmp.append(" ???");
			result = resultTmp.toString();
		}
		return result;
	}

	/**
	 * Récupère le message internationalisé
	 * 
	 * @param messageKey
	 *            la clef du message
	 * @param bundlesList
	 *            la liste des bundles pouvant contenir le messages
	 * @return le message internationalisé
	 */
	private static String getMessageForBundles(String messageKey, List<ResourceBundle> bundlesList) {
		String result = null;
		for (ResourceBundle bundle : bundlesList) {
			try {
				result = bundle.getString(messageKey);
				if (result != null) {
					break;
				}
			} catch (MissingResourceException e) {
				// pas de soucis, le message est peut être dans le bundle suivant
			}
		}
		return result;
	}

}
